package org.EasyDevelop.Builder;

import org.EasyDevelop.Bean.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class BaseBuilder {
    private static Logger logger = LoggerFactory.getLogger(BaseBuilder.class);
    public static void execute(){

        List<String> special = new ArrayList<>();

        //生成BaseTools

        special.add("import " + Constants.PACKAGE_ENTITY + ".baseEnum.DateTimePatternEnum" + ";");
        build(Arrays.asList("DateUtils"), Constants.PATH_UTILS,Constants.PACKAGE_UTILS,"utils",special);
        special.clear();

        build(Arrays.asList("DateTimePatternEnum"), Constants.PATH_ENTITY + "/baseEnum",Constants.PACKAGE_ENTITY + ".baseEnum","entity.baseEnum", special);

        //生成BaseMapper
        build(Arrays.asList("BaseMapper"),Constants.PATH_MAPPER,Constants.PACKAGE_MAPPER,"mappers", special);

        //生成pageSize枚举
        build(Arrays.asList("PageSize"),Constants.PATH_ENTITY + "/baseEnum",Constants.PACKAGE_ENTITY + ".baseEnum","entity.baseEnum", special);

        //生成基本类型BaseParam以及SimplePage
        build(Arrays.asList("BaseParam"),Constants.PATH_QUERY + "/base",Constants.PACKAGE_QUERY + ".base","entity.query.base", special);

        special.add("import " + Constants.PACKAGE_ENTITY + ".baseEnum.PageSize;");
        build(Arrays.asList("SimplePage"),Constants.PATH_QUERY + "/base",Constants.PACKAGE_QUERY + ".base","entity.query.base", special);
        special.clear();
        //生成分页查询对象
        build(Arrays.asList("PaginationResVo"),Constants.PATH_ENTITY_VO_PAGINATIONRESVO,Constants.PACKAGE_ENTITY_VO_PAGINATIONRESVO,"entity.vo", special);

        //生成ResponseVo
        build(Arrays.asList("ResponseVo"),Constants.PATH_ENTITY_VO_RESPONSE_VO,Constants.PACKAGE_ENTITY_VO_RESPONSE_VO,"entity.vo",special);


        //生成全局異常處理器
        special.add("import " + Constants.PACKAGE_UTILS + ".CommonResponseCodeEnum;");
        special.add("import " + Constants.PACKAGE_ENTITY_VO_RESPONSE_VO + ".ResponseVo;");
        special.add("import " + Constants.PACKAGE_CONTROLLER_BASE + ".BaseController;");
        special.add("import " + Constants.PACKAGE_EXCEPTION + ".BusinessException;");
        build(Arrays.asList("GlobalExceptionHandlerController"),Constants.PATH_CONTROLLER_ADVICE,Constants.PACKAGE_CONTROLLER_ADVICE,"controller",special);
        special.clear();

        //生成BaseController
        special.add("import " + Constants.PACKAGE_UTILS + ".CommonResponseCodeEnum;");
        special.add("import " + Constants.PACKAGE_ENTITY_VO_RESPONSE_VO + ".ResponseVo;");
        special.add("import " + Constants.PACKAGE_BASE + ".exception.BusinessException;");
        build(Arrays.asList("BaseController"),Constants.PATH_CONTROLLER_BASE,Constants.PACKAGE_CONTROLLER_BASE,"controller",special);
        special.clear();

        //生成BusinessException

        special.add("import " + Constants.PACKAGE_UTILS + ".Interface.BaseResponseCode;");
        build(Arrays.asList("BusinessException"),Constants.PATH_EXCEPTION,Constants.PACKAGE_EXCEPTION,"exception",special);
        special.clear();
        //生成CustomAssert接口

        special.add("import " + Constants.PACKAGE_BASE + ".exception.BusinessException;");
        build(Arrays.asList("CustomAssert"),Constants.PATH_UTILS + "/Interface",Constants.PACKAGE_UTILS + ".Interface","interface",special);
        special.clear();

        //生成BaseResponseGet接口
        build(Arrays.asList("BaseResponseGet"),Constants.PATH_UTILS + "/Interface",Constants.PACKAGE_UTILS + ".Interface","interface",special);

        //生成BaseResponseCode接口
        special.add("import " + Constants.PACKAGE_UTILS + ".Interface.CustomAssert;");
        special.add("import " + Constants.PACKAGE_UTILS + ".Interface.BaseResponseGet;");
        build(Arrays.asList("BaseResponseCode"),Constants.PATH_UTILS + "/Interface",Constants.PACKAGE_UTILS + ".Interface","interface",special);
        special.clear();

        //生成CommonResponseCodeEnum枚举
        special.add("import " + Constants.PACKAGE_BASE + ".exception.BusinessException;");
        special.add("import " + Constants.PACKAGE_UTILS + ".Interface.BaseResponseCode;");
        build(Arrays.asList("CommonResponseCodeEnum"),Constants.PATH_UTILS,Constants.PACKAGE_UTILS,"utils",special);
        special.clear();

        //Valid
        if(Boolean.valueOf(Constants.ENABLE_VALID)){

            build(Arrays.asList("ValidListBean"),Constants.PATH_CONTROLLER_BASE,Constants.PACKAGE_CONTROLLER_BASE,"controller",special);

            build(Arrays.asList("NameConversion"),Constants.PATH_UTILS + "/Interface",Constants.PACKAGE_UTILS + ".Interface","interface",special);

            special.add("import " + Constants.PACKAGE_UTILS + ".DefaultNameConversionUtils;\n" +
                    "import " + Constants.PACKAGE_UTILS + ".Interface.NameConversion;");
            build(Arrays.asList("EnumValid"),Constants.PATH_UTILS + "/annotation",Constants.PACKAGE_UTILS + ".annotation","annotation",special);
            special.clear();


            special.add("import " + Constants.PACKAGE_UTILS + ".Interface.NameConversion;");
            build(Arrays.asList("DefaultNameConversionUtils"),Constants.PATH_UTILS,Constants.PACKAGE_UTILS,"utils",special);

        }

        //Builder
        if(Boolean.valueOf(Constants.ENABLE_BUILDER)){
            build(Arrays.asList("Builder"),Constants.PATH_UTILS,Constants.PACKAGE_UTILS,"utils",special);
        }

        //Log
        if(Boolean.valueOf(Constants.ENABLE_LOGGING)){
            build(Arrays.asList("Log"),Constants.PATH_UTILS + "/annotation",Constants.PACKAGE_UTILS + "/annotation","annotation",special);

            special.add("import " + Constants.PACKAGE_UTILS + ".LoggingDecorator;");
            build(Arrays.asList("LogAspect"),Constants.PATH_UTILS + "/annotation",Constants.PACKAGE_UTILS + "/annotation","aspect",special);
            special.clear();

            build(Arrays.asList("LoggerModule"),Constants.PATH_UTILS + "/Interface",Constants.PACKAGE_UTILS + "/Interface","interface",special);

            special.add("import " + Constants.PACKAGE_UTILS + ".Interface.LoggerModule;");
            build(Arrays.asList("LoggingDecorator"),Constants.PATH_UTILS,Constants.PACKAGE_UTILS,"interface",special);
            special.clear();
        }





    }
    public static void build(List<String> fileNames, String path, String packagePath, String type, List<String> special){
        File folder = new File(path);
        if(!folder.exists()) folder.mkdirs();

        for (String fileName : fileNames) {
            File javaFile = new File(path, fileName + ".java");

            try(
                    OutputStream os = new FileOutputStream(javaFile);
                    OutputStreamWriter osw = new OutputStreamWriter(os,"UTF8");
                    BufferedWriter bw = new BufferedWriter(osw);
            ){
                String typeStr = null == type?"":type.replace(".","/") + "/";
                //get templatePath
                String templatePath = BaseBuilder.class.getClassLoader().getResource("template/"
                         + typeStr + fileName + ".txt").getPath();

//                System.out.println(templatePath);

                InputStream is = null;
                InputStreamReader isr = null;
                BufferedReader br = null;

                //package
                bw.write("package " + packagePath + ";");
                bw.newLine();
                bw.newLine();

                //special
                if(special.size()!=0){
                    for (String line : special) {
                        bw.write(line);
                        bw.newLine();
                    }
                }

                //read template and create .java
                try{
                    is = new FileInputStream(templatePath);
                    isr = new InputStreamReader(is,"UTF8");
                    br = new BufferedReader(isr);
                    String line = null;
                    while((line = br.readLine())!=null){
                        bw.write(line);
                        bw.newLine();
                    }
                    bw.flush();
                }catch (Exception e){
                    logger.error("读取模板 {} 失败! {} ",fileName,e);
                }


            }catch (Exception e){
                logger.error("生成基础类 {} 失败! {} ",fileName,e);
            }
        }

    }

}
